home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gigarom 1
/
Gigarom Macintosh Archives (Quantum Leap)(CDRM1080320)(1993).iso
/
FILES
/
BBS
/
HERMES
/
ProtMover6.1.cpt
/
ASCII
/
ASCII.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-29
|
7KB
|
356 lines
/* ASCII Transfer External for Hermes © 1990 By John Raymonds.
Written in THINK C 4.0.1 as an example external for Hermes protocol
developers. Use of any code shown below in any program other than
an external to be used with Hermes requires written permission from
the author:
John Raymonds
76174,205 (Compuserve)
D3885 (AppleLink)
Comments and suggestions are welcome.
040590 JR - Fixed Send.c (added startTime, bytesDone reset,
and bytesTotal set)
050190 JR - Changed read.c and write.c to support new Hermes.h
information. Added ++prp->filesDone in Receive.c
so Hermes knows it was a good upload.
052290 JR - Changed over to the new Protocol Mover interface.
052990 JR - See the version history in the About notes for
changes.
*/
#include "Protocol.h"
#include "ASCII.h"
#include <:Mac #includes:SetUpA4.h>
ProtoRecPtr PRP;
ProtoGloPtr PGP;
pascal OsErr main(message, prp, refCon)
register int message;
register ProtoRecPtr prp;
long refCon;
{
register OsErr err;
register ProtoGloPtr pgp;
int doProtocol();
RememberA0();
SetUpA4();
PRP = prp;
err = noErr;
if (!prp->protoData) {
/* set up external globals if they do not exist */
prp->protoData = NewHandle((long) sizeof(ProtoGloRec));
err = MemError();
if (!err) {
/* let's lock the globals down and keep them locked until
we exit the external.
*/
MoveHHi(prp->protoData);
HLock(prp->protoData);
/* set up a global pointer to the globals we just allocated */
PGP = *((ProtoGloHand) prp->protoData);
/* make it a register variable since we will use it a
number of times...
*/
pgp = PGP;
ClearBlock(pgp, (long) sizeof(ProtoGloRec));
/* make a zero length handle for the StackSaver */
pgp->SSR.stackData = NewHandle(0L);
err = MemError();
if (err) {
HUnlock(prp->protoData);
DisposHandle(prp->protoData);
prp->protoData = 0L;
}
else {
/* initialize our globals... */
pgp->MIOPin.ioRefNum = prp->mRefIn;
pgp->MIOPout.ioRefNum = prp->mRefOut;
RWPrefs(FALSE);
}
}
}
else {
/* set up a global pointer to the globals we allocated before */
PGP = *((ProtoGloHand) prp->protoData);
pgp = PGP;
}
if (!err) {
/* use the StackSaver JumpBack routine to enter our code...
On the first call (handle size of pgp->SSR = 0) JumpBack
will simply call doProtocol which is defined elsewhere.
On calls generated after a Return was executed JumpBack
will restore the stack to the state it was in during the
call the Return and being execution there.
*/
err = JumpBack(message, prp, refCon, &pgp->SSR, doProtocol);
if (err) {
/* external has returned with a non-zero result. We are
done so dispose of all of our stuff.
*/
if (prp->protoData) {
if (pgp->SSR.stackData) {
DisposHandle(pgp->SSR.stackData);
}
HUnlock(prp->protoData);
DisposHandle(prp->protoData);
prp->protoData = 0L;
}
}
}
RestoreA4();
return(err);
}
/* This is the routine pasted to JumpBack. Notice that the arguments
are the same as those defined for the external itself. As note that
all functions (unlike the external itself) use 'C' calling conventions.
*/
int doProtocol(message, prp, refCon)
int message;
ProtoRecPtr prp;
long refCon;
{
register OsErr err;
err = noErr;
switch(message) {
case SEND:
err = SendASCII();
break;
case RECEIVE:
err = RecvASCII();
break;
case SETPREFS:
doSetPrefs();
default:
err = 128;
break;
}
/* make sure our async send buffers are written out */
FlushWrite();
return(err);
}
tellerror(errornum)
int errornum;
{
/* set the errReason */
SetError(errornum);
/* immediately return to Hermes to show error: timeOut = 0 */
Return(0, &PGP->SSR);
}
SetError(errornum)
register int errornum;
{
register int i;
register StringPtr eText;
register ProtoRecPtr prp;
Str255 errText, nText;
prp = PRP;
++PGP->errCount;
switch(errornum) {
case TIMEOUT:
eText = (StringPtr) "\pTimeout";
break;
case TOOMANYERR:
eText = (StringPtr) "\pToo many errors";
break;
case NOTTEXT:
eText = (StringPtr) "\pFile was not 'TEXT'";
break;
case NOCONTINUE:
eText = (StringPtr) "\pPause not continued";
break;
default:
eText = (StringPtr) "\pMac OS Error";
break;
}
/* dispose of any error string that might already be there for some
reason.
*/
if (prp->errReason) {
DisposHandle(prp->errReason);
}
/* show the error list */
errText[0] = 0;
for (i = 0; i<3; i++) {
if (!PGP->errList[i]) {
break;
}
NumToString((long) PGP->errList[i], nText);
Pstrcat(errText, nText);
Pstrcad(errText, ',');
}
/* tack on the current error */
NumToString((long) errornum, nText);
Pstrcat(errText, nText);
Pstrcat(errText, "\p = ");
Pstrcat(errText, eText);
Pstrcat(errText, "\p (");
NumToString((long) PGP->errCount, nText);
Pstrcat(errText, nText);
Pstrcat(errText, "\p errors)");
prp->errReason = NewString(errText);
prp->F.B.newError = TRUE;
/* rotate error list */
PGP->errList[2] = PGP->errList[1];
PGP->errList[1] = PGP->errList[0];
/* add current error to the list */
PGP->errList[0] = errornum;
/* This routine uses a lot of stack space so we are not going to
do a Return here.
*/
}
ClearBlock(aPtr, size)
register Ptr aPtr;
register long size;
{
asm {
tst.l size
beq.s @theEnd
btst.l #0, size
beq.s @even
;
; size is odd so we must clear by byte
;
@loop1 clr.b (aPtr)+
subq.l #1, size
bne.s @loop1
bra.s @theEnd
@even btst.l #1, size
beq.s @loop3
;
; size is not a multiple of 4 so we must clear by word
;
@loop2 clr.w (aPtr)+
subq.l #2, size
bne.s @loop2
bra.s @theEnd
;
; size is a multiple of 4 so we can clear by long
;
@loop3 clr.l (aPtr)+
subq.l #4, size
bne.s @loop3
@theEnd
}
}
Pstrcpy(s, t)
register StringPtr s, t;
{
register int i;
asm {
clr.w i
move.b (t), i
@loop move.b (t)+, (s)+
dbf i, @loop
}
}
Pstrcat(s, t)
register StringPtr s, t;
{
register int i;
asm {
move.l s, a0
clr.w i
move.b (s)+, i
adda.w i, s
move.b (t)+, i
beq.s @theEnd
add.b i, (a0)
subq.w #1, i
@loop move.b (t)+, (s)+
dbf i, @loop
@theEnd
}
}
Pstrcad(s, c)
register StringPtr s;
register char c;
{
register int i;
asm {
addq.b #1, (s)
clr.w i
move.b (s), i
adda.w i, s
move.b c, (s)
}
}
CenterWindow(wp, h, v)
register WindowPtr wp;
register int h, v;
{
Rect wRect;
Rect ScrnRect;
int top, left;
GrafPtr savePort;
register int dx, dy;
ScrnRect = *((Rect *) (*((Handle) CurrentA5)-116));
ScrnRect.top += MBarHeight;
GetPort(&savePort);
SetPort(wp);
wRect = wp->portRect;
LocalToGlobal(&topLeft(wRect));
LocalToGlobal(&botRight(wRect));
top = wRect.top;
left = wRect.left;
SetPort(savePort);
CenterRect(&wRect, &ScrnRect);
dx = wRect.left-ScrnRect.left;
dy = wRect.top-ScrnRect.top;
if ((h > 1) && dx) {
dx = dx*h/100;
}
if ((v > 1) && dy) {
dy = dy*h/100;
}
if (h) {
h = ScrnRect.left+dx;
}
else {
h = left;
}
if (v) {
v = ScrnRect.top+dy;
}
else {
v = top;
}
MoveWindow(wp, h, v, FALSE);
}
CenterRect(RtoCent, r)
register Rect *RtoCent, *r;
{
int dx = MidPoint(r->left, r->right);
int dy = MidPoint(r->top, r->bottom);
dx -= MidPoint(RtoCent->left, RtoCent->right);
dy -= MidPoint(RtoCent->top, RtoCent->bottom);
OffsetRect(RtoCent, dx, dy);
}
int MidPoint(a, b)
register int a, b;
{
return((a+b)/2);
}